﻿using OpenCvSharp;
using OpenCvSharp.Extensions;
using OpenCvSharp.WpfExtensions;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Media.Imaging;

namespace OpenCvSharpExtension
{
    /// <summary>
    /// 位图工具
    /// </summary>
    public static class BitmapHelper
    {
        /// <summary>
        /// 使用OpenCV对图像文件进行解码并转换成<see cref="WriteableBitmap"/>，OPENCV比WPF支持更多的图像编码方式。
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        public static WriteableBitmap LoadImageByOpenCV(string file)
        {
            Mat mat = Cv2.ImRead(file);
            return WriteableBitmapConverter.ToWriteableBitmap(mat);

        }
        /// <summary>
        /// 位块传输，将<see cref="Bitmap"/>中的图形数据写入<see cref="WriteableBitmap"/>。（此方法需要允许不安全代码）
        /// </summary>
        /// <param name="dst"></param>
        /// <param name="src"></param> 
        public unsafe static void Blit(this WriteableBitmap dst, Bitmap src)
        {
            int srcw = src.Width;
            int srch = src.Height;
            var rect = new Rectangle(0, 0, srcw, srch);
            int left = rect.Left < 0 ? 0 : rect.Left;
            int top = rect.Top < 0 ? 0 : rect.Top;
            int right = rect.Right > srcw ? srcw : rect.Right;
            int bottom = rect.Bottom > srch ? srch : rect.Bottom;
            if (left >= right || top >= bottom) return;

            BitmapData srcdata = src.LockBits(new Rectangle(0, 0, srcw, srch), ImageLockMode.ReadOnly, src.PixelFormat);
            dst.Lock();
            var srcints = (int*)srcdata.Scan0;
            var dstints = (int*)dst.BackBuffer.ToPointer();
            for (int j = top; j < bottom; ++j)
            {
                int y = j * srcw;
                for (int i = left; i < right; ++i)
                {
                    int index = y + i;
                    dstints[index] = srcints[index];
                }
            }
            dst.AddDirtyRect(new Int32Rect(left, top, right - left, bottom - top));
            src.UnlockBits(srcdata);
            dst.Unlock();
        }
        /// <summary>
        /// 位块传输，将<see cref="Mat"/>中的数据写入<see cref="WriteableBitmap"/>
        /// </summary>
        /// <param name="dst"></param>
        /// <param name="src"></param>
        public static void Blit(this WriteableBitmap dst, Mat src)
        {
            WriteableBitmapConverter.ToWriteableBitmap(src, dst);
        }
        /// <summary>
        /// 转换为<see cref="WriteableBitmap"/>
        /// </summary>
        /// <param name="src"></param>
        /// <returns></returns>
        public static WriteableBitmap ToWriteableBitmap(this Mat src)
        {
            return WriteableBitmapConverter.ToWriteableBitmap(src);
        }
    }
}
